package com.shy.example.hystrix.service.impl;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.shy.example.hystrix.service.DeptService;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class DeptServiceImpl implements DeptService {

    @Override
    public String deptInfo_Ok(Integer id) {
        return "线程池： " + Thread.currentThread().getName() + " deptInfo_Ok, id: " + id;
    }
    //一旦该方法失败并抛出了异常信息后，会自动调用  @HystrixCommand 注解标注的 fallbackMethod 指定的方法
    @HystrixCommand(fallbackMethod = "dept_TimeoutHandler",
                commandProperties = {
                    //规定 5 秒钟以内就不报错，正常运行，超过 5 秒就报错，调用指定的方法
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
                })
    @Override
    public String deptInfo_Timeout(Integer id) {
        int outTime = 6;
        try {
            TimeUnit.SECONDS.sleep(outTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池： " + Thread.currentThread().getName() + "   deptInfo_Timeout, id:  " + id + "耗时: " + outTime;
    }

    @HystrixCommand(fallbackMethod = "deptCircuitBreaker_fallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //是否开启熔断器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //统计时间窗内请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), //在统计时间窗口期以内，请求失败率达到 60% 时进入熔断状态
    })
    @Override
    public String deptCircuitBreaker(Integer id) {
        if (id < 0){
            throw new RuntimeException("本网站提醒您， id不能是负数！");
        }
        String serialNum = UUID.randomUUID().toString();
        return Thread.currentThread().getName() + "\t" + "调用成功， 流水号为: " + serialNum;
    }

    // 当服务出现故障后，调用该方法给出友好提示
    public String dept_TimeoutHandler(Integer id){
        return "本网站提醒您，系统繁忙请稍后再试！" + "线程池： " + Thread.currentThread().getName() + "  deptInfo_Timeout,id:  " + id;
    }

    public String deptCircuitBreaker_fallback(Integer id){
        return "本网站提醒您，id不能是负数，请稍后重试！\t id: " + id;
    }
}
